package com.thread.threadfirst.javaBase;

/**
 * 静态代码块、普通代码块、构造方法执行顺序
 * 在继承的前提下，执行Father son = new Son();这句时，执行顺序：
 * Father类静态代码块——Son类静态代码块——Father类普通方法——Father类构造方法——Son类普通方法——Son类构造方法
 * 而第二次new Son():时就不执行父类子类静态代码块 直接从父类普通方法开始按照顺序执行了，因为静态代码块在类加载的时候执行，而且只执行一次，之后再创建对象实例就不执行了。
 */
public class StaticExtends {
    //类在载入内存时，先执行静态代码块。
    static {
        System.out.println("静态方法……");
    }

    //这个方法中什么都没有 就启动时，上面的静态方法会执行，因为此StaticExtends类载入到内存中了，而且在类载入时会先执行静态代码块。
    public static void main(String[] args) {
        Father son = new Son();    //声明为Father类,son1静态方法和Father类绑定，即调用son1.staticMethod()就调用的Father类的staticMethod方法。
        son.method();  //注意：就近调用子类中的方法，而不是父类的同名方法。
        son.staticMethod();  //注意：因为上面声明的是Father类，所以这里是调用Father类的静态方法，下面同理。
        System.out.println("==================================");

        Son son2 = new Son(); //注意：这里声明为Son类，则下面的son2.staticMethod();就是在调用Son类中的static方法。
        son2.method();
        son2.staticMethod(); //如果将Son类的静态方法注释掉，那么此处调用的就是Father类的静态方法了，所以静态方法可以被继承，但不可以被重写，即便是Father类、Son类中都有一个返回类型、方法名、参数列表均与之相同的静态方法，
        // 那么该子类实际上只是将父类中的该同名方法进行了隐藏，而非重写，即是两个没有关系的方法，他们的行为也并不具有多态性。
        Son.staticMethod();  //注意：如果将Son类的静态方法注释掉，此处也会改为调用Father类的静态方法。
    }
}

class Father {

    static {
        System.out.println("This is Father Static area Code... ");
    }

    {
        System.out.println("This is Father General area Code...");
    }

    public Father() {
        System.out.println("This is Father Construct Method...");
    }

    void method() {
        System.out.println("父类方法");
    }

    static void staticMethod() {
        System.out.println("父类静态方法");
    }
}

class Son extends Father {

    static {
        System.out.println("This is Son Static area Code... ");
    }

    {
        System.out.println("This is Son General area Code...");
    }

    public Son() {
        System.out.println("This is Son Construct Method...");
    }

    void method() {
        System.out.println("子类方法");
    }

    static void staticMethod() {
        System.out.println("子类静态方法");      //注意：如果将此Son类的静态方法注释掉，那么上面son2.staticMethod();调用的就是Father类的静态方法了，所以静态方法可以被继承，但不可以被重写，即便是Father类、Son类中都有相同的static方法，那也是两个没有关联的方法。
    }
}
